#include "thread.h"       // 包含 Thread 类的头文件
#include "utils.h"        // 包含工具函数（如获取线程ID）

namespace fiber {

// 这两个变量由每个线程单独持有
// 线程局部存储：指向当前线程的指针（每个线程有独立副本）   
// thread_local 使得变量线程独立    C++11及以上标准引入的关键字
static thread_local Thread *cur_thread = nullptr;
// 线程局部存储：当前线程的名称（每个线程有独立副本）  
static thread_local std::string cur_thread_name = "UNKNOW";

Thread::Thread(std::function<void()> cb, const std::string &name = "UNKNOW") 
: m_cb(cb), m_name(name) {
    if (name.empty()) {
        m_name = "UNKNOW";  // 确保名称不为空
    }

    // 创建线程：调用 pthread_create，执行 run 静态方法
    int rt = pthread_create(&m_thread, nullptr, &Thread::run, this);
    if (rt) {
        // 创建失败时输出错误信息并抛出异常
        std::cout << "pthread_create error, name:" << m_name << std::endl;
        throw std::logic_error("pthread_create");
    }
}

Thread::~Thread() {
    if (m_thread) {
        // 线程未被 join 时，自动分离线程
        pthread_detach(m_thread);
        m_thread = 0;
    }
}

void Thread::join() {
    if (m_thread) {
        // 调用 pthread_join 等待线程退出
        int rt = pthread_join(m_thread, nullptr);
        if (rt) {
            // 等待失败时输出错误信息并抛出异常
            std::cout << "pthread_join error,name:" << m_name << std::endl;
            throw std::logic_error("pthread_join");
        }
        m_thread = 0;  // 重置线程ID，标记已处理
    }
}

void* Thread::run(void *arg) {
    Thread *thread = (Thread *)arg;  // 将参数转换为 Thread 对象指针
    
    // 更新线程局部存储，记录当前线程信息
    cur_thread = thread;
    cur_thread_name = thread->m_name;
    thread->m_id = fiber::GetThreadId();  // 获取并保存线程ID
    
    // 设置线程名称（截断为15字符，避免超出系统限制）
    pthread_setname_np(pthread_self(), thread->m_name.substr(0, 15).c_str());
    
    // 交换回调函数，避免外部引用失效
    std::function<void()> cb;
    cb.swap(thread->m_cb);
    
    // 执行用户提供的回调函数
    cb();
    return 0;
}

Thread *Thread::GetThis() { return cur_thread; }

const std::string &Thread::GetName() { return cur_thread_name; }

void Thread::SetName(const std::string &name) {
    if (name.empty()) {
        return;  // 名称为空则不设置
    }

    // 更新当前线程对象的名称（如果存在）
    if (cur_thread) {
        cur_thread->m_name = name;
    }

    // 更新线程局部存储中的名称
    cur_thread_name = name;
}

}  // namespace fiber